import { CheckUtil } from '@/utils';

export const FileUtil = {
  fileToBase64(file) {
    if (!CheckUtil.isBrowser() || !CheckUtil.isFile(file)) {
      return Promise.reject(new Error('转换异常'));
    }
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        resolve(reader.result);
      };
      reader.onerror = () => {
        reject(new Error('转换失败'));
      };
    });
  },

  // eslint-disable-next-line no-unused-vars
  base64ToBlob(base64Data, onlyFileFlag = true, type) {
    const arr = base64Data.split(',');
    const mime = arr[0].match(/:(.*?);/)[1] || type;

    // 去掉url的头，并转化为byte
    const bytes = window.atob(arr[1]);
    // 处理异常,将ascii码小于0的转换为大于0
    let bytesLen = bytes.length;
    const ab = new ArrayBuffer(bytesLen);
    // 生成视图（直接针对内存）：8位无符号整数，长度1个字节
    const ia = new Uint8Array(ab);
    while (bytesLen--) {
      ia[bytesLen] = bytes.charCodeAt(bytesLen);
    }
    return new Blob([ab], {
      type: mime,
    });
  },

  /**
   * @param file
   * @param onlyFileFlag 仅包含文件内容
   * @returns {Promise}
   */
  blobToBase64(file, onlyFileFlag = true) {
    if (!CheckUtil.isFile(file)) {
      return;
    }

    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      let res;
      reader.readAsDataURL(file);
      reader.onload = () => {
        res = onlyFileFlag ? reader.result.split(',')[1] : reader.result;
      };
      reader.onerror = (error) => {
        reject(error);
      };
      reader.onloadend = () => {
        resolve(res);
      };
    });
  },

  /**
   * @param base64Data <只包含文件内容>
   * @returns {Uint8Array}
   */
  base64ToBytes(base64Data) {
    const ab = new ArrayBuffer(base64Data.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < base64Data.length; i++) {
      ia[i] = base64Data.charCodeAt(i);
    }
    return ia;
  },

  async blobToByteArr(file) {
    return this.base64ToBytes(await this.blobToBase64(file));
  },

  bytesToBlob(bytes, type) {
    const option = {};
    if (type) {
      option.type = type;
    }
    return new Blob(bytes, option);
  },
};
